
package com.hlkj.pay.gateway.order.impl;
/*
 * Hlpay-Plus aggregate payment system.
 * Copyright (c) 2024-2025 Hlpay Team Copyright has the right of final interpretation.
 */

import java.util.List;
import java.util.Map;

import org.springframework.stereotype.Service;

import com.hlkj.framework.common.util.collection.CollectionUtils;
import com.hlkj.framework.common.util.json.JsonUtils;
import com.hlkj.pay.dto.common.RsaConfig;
import com.hlkj.pay.dto.merchant.MerchantAccessDto;
import com.hlkj.pay.dto.order.OrderFundDto;
import com.hlkj.pay.infrastructure.model.merchant.MerchantAccessInfoDO;
import com.hlkj.pay.infrastructure.model.order.*;
import com.hlkj.pay.infrastructure.model.payment.MerchantPaymentDO;
import com.hlkj.pay.infrastructure.model.payment.MerchantPaymentDetailDO;
import com.hlkj.pay.service.common.IPlatFormConfigService;
import com.hlkj.pay.util.OpenApiParamsUtils;
import com.hlkj.pay.util.SignUtils;
import com.hlkj.pay.vo.openapi.merchant.resp.access.OpenApiMerchantAccessResp;
import com.hlkj.pay.vo.openapi.merchant.resp.access.OpenApiOrderSettleResp;
import com.hlkj.pay.vo.openapi.order.resp.AcctRefundOrderApiResp;
import com.hlkj.pay.vo.openapi.order.resp.OpenApiOrderTransferResp;
import com.hlkj.pay.vo.openapi.order.resp.OpenApiOrderWithdrawResp;
import com.hlkj.pay.vo.openapi.order.resp.PaymentApiResp;
import com.hlkj.pay.vo.order.OpenApiResult;
import com.hlkj.pay.vo.order.resp.PayOrderResp;
import com.hlkj.pay.vo.order.resp.RefundOrderResp;
import com.hlkj.pay.vo.order.resp.acct.PayOrderFundResp;

import cn.hutool.core.bean.BeanUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

/**
 * @author HlpayTeam
 * @date 2024/11/07 11:04
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class OrderNotifyParamsHandler {

    private final IPlatFormConfigService platFormConfigService;

    public OpenApiResult<PayOrderResp> payOrderNotifyData(PayOrderDO payOrderDO, List<OrderFundDetailDO> payOrderFundList) {
        PayOrderResp payOrderResp = BeanUtil.copyProperties(payOrderDO, PayOrderResp.class);
        if (!CollectionUtils.isEmpty(payOrderFundList)) {
            List<PayOrderFundResp> payOrderFundResps = BeanUtil.copyToList(payOrderFundList, PayOrderFundResp.class);
            payOrderResp.setAcctInfos(JsonUtils.toJsonStringNotNull(payOrderFundResps));
            // payOrderResp.setAcctInfos(BeanUtil.copyToList(payOrderFundList,
            // PayOrderFundResp.class));
        }
        OpenApiResult<PayOrderResp> commonResult = OpenApiResult.success();
        commonResult.setAppId(payOrderDO.getAppId());
        commonResult.setSignType(payOrderDO.getSignType());
        commonResult.setSn(payOrderDO.getOrderSn());
        commonResult.setTimestamp(String.valueOf(System.currentTimeMillis() / 1000));
        commonResult.setData(payOrderResp);
        if (commonResult.getData() != null) {
            RsaConfig rsaConfig = platFormConfigService.getRsaConfig();
            // 签名参数
            Map<String, Object> map = BeanUtil.beanToMap(commonResult);
            try {
                String sign = SignUtils.signRsa(map, rsaConfig.getPrivateKey(), commonResult.getSignType());
                commonResult.setSign(sign);
            }
            catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
        return commonResult;
    }

    public OpenApiResult<RefundOrderResp> refundOrderNotifyData(RefundOrderDO refundOrderDO) {
        RefundOrderResp payOrderResp = BeanUtil.copyProperties(refundOrderDO, RefundOrderResp.class);
        payOrderResp.setStatus(refundOrderDO.getRefundStatus());
        payOrderResp.setReason(refundOrderDO.getRefundReason());
        payOrderResp.setMessage(refundOrderDO.getBankMsg());
        OpenApiResult<RefundOrderResp> commonResult = OpenApiResult.success();
        commonResult.setAppId(refundOrderDO.getAppId());
        commonResult.setSignType(refundOrderDO.getSignType());
        commonResult.setSn(refundOrderDO.getSn());
        commonResult.setTimestamp(String.valueOf(System.currentTimeMillis() / 1000));
        commonResult.setData(payOrderResp);
        if (commonResult.getData() != null) {
            RsaConfig rsaConfig = platFormConfigService.getRsaConfig();
            // 签名参数
            Map<String, Object> map = BeanUtil.beanToMap(commonResult);
            try {
                String sign = SignUtils.signRsa(map, rsaConfig.getPrivateKey(), commonResult.getSignType());
                commonResult.setSign(sign);
            }
            catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
        return commonResult;
    }

    public OpenApiResult<OpenApiOrderSettleResp> merchantAccessSettleNotifyData(OrderSettleDO merchantAccessDto) {
        OpenApiOrderSettleResp openApiMerchantAccessResp = BeanUtil.copyProperties(merchantAccessDto, OpenApiOrderSettleResp.class);
        OpenApiResult<OpenApiOrderSettleResp> commonResult = OpenApiResult.success();
        commonResult.setAppId(merchantAccessDto.getAppId());
        commonResult.setSignType(merchantAccessDto.getSignType());
        commonResult.setSn(merchantAccessDto.getSn());
        commonResult.setTimestamp(String.valueOf(System.currentTimeMillis() / 1000));
        commonResult.setData(openApiMerchantAccessResp);
        if (commonResult.getData() != null) {
            RsaConfig rsaConfig = platFormConfigService.getRsaConfig();
            // 签名参数
            Map<String, Object> map = BeanUtil.beanToMap(commonResult);
            try {
                String sign = SignUtils.signRsa(map, rsaConfig.getPrivateKey(), commonResult.getSignType());
                commonResult.setSign(sign);
            }
            catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
        return commonResult;
    }

    public OpenApiResult<AcctRefundOrderApiResp> openApiMerchantAccessResp(OrderFundDto orderFundDto) {
        List<OrderFundDetailDO> orderFundDetailList = orderFundDto.getOrderFundDetailList();
        OrderFundDO orderFund = orderFundDto.getOrderFund();
        AcctRefundOrderApiResp acctPayOrderApiResp = new AcctRefundOrderApiResp();
        List<PayOrderFundResp> payOrderFundResps = BeanUtil.copyToList(orderFundDetailList, PayOrderFundResp.class);
        acctPayOrderApiResp.setAcctInfos(JsonUtils.toJsonStringNotNull(payOrderFundResps));
        acctPayOrderApiResp.setBatchNo(orderFund.getBatchNo());
        acctPayOrderApiResp.setPayOrderNo(orderFund.getPayOrderNo());
        acctPayOrderApiResp.setMchOrderNo(orderFundDto.getMchOrderNo());
        acctPayOrderApiResp.setMchAcctOrderNo(orderFund.getMchAcctOrderNo());
        acctPayOrderApiResp.setMchAcctRefundOrderNo(orderFund.getMchAcctRefundOrderNo());

        OpenApiResult<AcctRefundOrderApiResp> commonResult = OpenApiResult.success();
        commonResult.setAppId(orderFund.getAppId());
        commonResult.setSignType(orderFund.getSignType());
        commonResult.setSn(orderFund.getSn());
        commonResult.setTimestamp(String.valueOf(System.currentTimeMillis() / 1000));
        commonResult.setData(acctPayOrderApiResp);
        if (commonResult.getData() != null) {
            RsaConfig rsaConfig = platFormConfigService.getRsaConfig();
            // 签名参数
            Map<String, Object> map = BeanUtil.beanToMap(commonResult);
            try {
                String sign = SignUtils.signRsa(map, rsaConfig.getPrivateKey(), commonResult.getSignType());
                commonResult.setSign(sign);
            }
            catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
        return commonResult;
    }

    public OpenApiResult<OpenApiMerchantAccessResp> merchantAccessNotifyData(MerchantAccessDto merchantAccessDto) {
        MerchantAccessInfoDO merchantAccessInfo = merchantAccessDto.getMerchantAccessInfo();
        OpenApiMerchantAccessResp openApiMerchantAccessResp = OpenApiParamsUtils.openApiMerchantAccessResp(merchantAccessDto);
        OpenApiResult<OpenApiMerchantAccessResp> commonResult = OpenApiResult.success();
        commonResult.setAppId(merchantAccessInfo.getAppId());
        commonResult.setSignType(merchantAccessInfo.getSignType());
        commonResult.setSn(merchantAccessInfo.getSn());
        commonResult.setTimestamp(String.valueOf(System.currentTimeMillis() / 1000));
        commonResult.setData(openApiMerchantAccessResp);
        if (commonResult.getData() != null) {
            RsaConfig rsaConfig = platFormConfigService.getRsaConfig();
            // 签名参数
            Map<String, Object> map = BeanUtil.beanToMap(commonResult);
            try {
                String sign = SignUtils.signRsa(map, rsaConfig.getPrivateKey(), commonResult.getSignType());
                commonResult.setSign(sign);
            }
            catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
        return commonResult;
    }

    public OpenApiResult<PaymentApiResp> paymentOrderNotifyData(MerchantPaymentDO merchantPaymentDO, MerchantPaymentDetailDO merchantPaymentDetailDO) {
        PaymentApiResp payOrderResp = OpenApiParamsUtils.paymentApiResp(merchantPaymentDO, merchantPaymentDetailDO);
        OpenApiResult<PaymentApiResp> commonResult = OpenApiResult.success();
        commonResult.setAppId(merchantPaymentDO.getAppId());
        commonResult.setSignType(merchantPaymentDO.getSignType());
        commonResult.setSn(merchantPaymentDO.getSn());
        commonResult.setTimestamp(String.valueOf(System.currentTimeMillis() / 1000));
        commonResult.setData(payOrderResp);
        if (commonResult.getData() != null) {
            RsaConfig rsaConfig = platFormConfigService.getRsaConfig();
            // 签名参数
            Map<String, Object> map = BeanUtil.beanToMap(commonResult);
            try {
                String sign = SignUtils.signRsa(map, rsaConfig.getPrivateKey(), commonResult.getSignType());
                commonResult.setSign(sign);
            }
            catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
        return commonResult;
    }
    public OpenApiResult<OpenApiOrderTransferResp> transferOrderNotifyData(OrderTransferDO orderTransferDO) {
        OpenApiOrderTransferResp payOrderResp = BeanUtil.copyProperties(orderTransferDO, OpenApiOrderTransferResp.class);
        OpenApiResult<OpenApiOrderTransferResp> commonResult = OpenApiResult.success();
        commonResult.setAppId(orderTransferDO.getAppId());
        commonResult.setSignType(orderTransferDO.getSignType());
        commonResult.setSn(orderTransferDO.getSn());
        commonResult.setTimestamp(String.valueOf(System.currentTimeMillis() / 1000));
        commonResult.setData(payOrderResp);
        if (commonResult.getData() != null) {
            RsaConfig rsaConfig = platFormConfigService.getRsaConfig();
            // 签名参数
            Map<String, Object> map = BeanUtil.beanToMap(commonResult);
            try {
                String sign = SignUtils.signRsa(map, rsaConfig.getPrivateKey(), commonResult.getSignType());
                commonResult.setSign(sign);
            }
            catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
        return commonResult;
    }
    public OpenApiResult<OpenApiOrderWithdrawResp> withdrawOrderNotifyData(OrderWithdrawDO orderWithdrawDO) {
        OpenApiOrderWithdrawResp payOrderResp = BeanUtil.copyProperties(orderWithdrawDO, OpenApiOrderWithdrawResp.class);
        OpenApiResult<OpenApiOrderWithdrawResp> commonResult = OpenApiResult.success();
        commonResult.setAppId(orderWithdrawDO.getAppId());
        commonResult.setSignType(orderWithdrawDO.getSignType());
        commonResult.setSn(orderWithdrawDO.getSn());
        commonResult.setTimestamp(String.valueOf(System.currentTimeMillis() / 1000));
        commonResult.setData(payOrderResp);
        if (commonResult.getData() != null) {
            RsaConfig rsaConfig = platFormConfigService.getRsaConfig();
            // 签名参数
            Map<String, Object> map = BeanUtil.beanToMap(commonResult);
            try {
                String sign = SignUtils.signRsa(map, rsaConfig.getPrivateKey(), commonResult.getSignType());
                commonResult.setSign(sign);
            }
            catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
        return commonResult;
    }
}
